﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.Exchange.WebServices.Data;
using System.Windows.Threading;
using Microsoft.Xrm.Sdk.Discovery;

namespace Email_Validator
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {

        crmauthinfo CrmAuth = null;
        exchangeauthinfo ExchangeAuth = null;

        public MainWindow()
        {
            InitializeComponent();
        }

        private void getorgsBtn_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                DisableCrmControls();
                ExtensionMethods.Refresh(getorgsBtn);
                if ((bool)onpremChkBox.IsChecked && string.IsNullOrEmpty(domainTxtBox.Text))
                {
                    MessageBox.Show("Domain value is null. Please provide the Domain information and try again.");
                    EnableCrmControls();
                    return;
                }

                CrmAuth = new crmauthinfo(discoveryTxtBox.Text, usernameTxtBox.Text, passwordBox.Password, domainTxtBox.Text, orgsComboBox, (bool)isQueuechkbox.IsChecked, txtTargetMailbox.Text);
                CrmAuth.Run();
                if (CrmAuth.DiscoProxy == null)
                {
                    EnableCrmControls();
                    return;
                }
                getorgsBtn.Content = "Organizations Retrieved";
                CheckStatusAndEnableGo();
            }
            catch (Exception ex)
            {
                if (ex.InnerException != null)
                {
                    if (ex.InnerException.Message == "Authentication Failure")
                    {
                        MessageBox.Show("CRM Authentication Failed. Please check your credentials.");
                        EnableCrmControls();
                        return;
                    }
                }
                if (!string.IsNullOrEmpty(ex.Message) && ex.Message == "Access is denied.")
                {
                    MessageBox.Show("CRM Authentication Failed. Please check your credentials.");
                    EnableCrmControls();
                    return;
                }

                MessageBox.Show(GetErrorDetail(ex), "Exception - CRM Authentication");
                EnableCrmControls();
                return;
            }
        }

        private void EnableCrmControls()
        {
            getorgsBtn.IsEnabled = true;
            usernameTxtBox.IsEnabled = true;
            passwordBox.IsEnabled = true;
            domainTxtBox.IsEnabled = true;
            getorgsBtn.Content = "Sign In";
            discoveryTxtBox.IsEnabled = true;
            domainTxtBox.IsEnabled = true;
            //crmcurrentcredChkBox.IsEnabled = false;
            onpremChkBox.IsEnabled = true;
        }

        private void DisableCrmControls()
        {
            usernameTxtBox.IsEnabled = false;
            passwordBox.IsEnabled = false;
            domainTxtBox.IsEnabled = false;
           //crmcurrentcredChkBox.IsEnabled = false;
            onpremChkBox.IsEnabled = false;
            discoveryTxtBox.IsEnabled = false;
            getorgsBtn.Content = "Retrieving...";
            getorgsBtn.IsEnabled = false;
        }

        public static string GetErrorDetail(Exception ex)
        {
            StringBuilder errordetail = new StringBuilder(ex.Message);
            errordetail.Append(Environment.NewLine);
            errordetail.Append(ex.InnerException);
            errordetail.Append(Environment.NewLine);
            errordetail.Append(ex.StackTrace);
            return errordetail.ToString();
        }

        private void onpremChkBox_Checked(object sender, RoutedEventArgs e)
        {
            domainTxtBox.IsEnabled = true;
            discoveryTxtBox.Text = "http://<server>/XrmServices/2011/Discovery.svc";
        }
        private void onpremChkBox_Unchecked(object sender, RoutedEventArgs e)
        {
            domainTxtBox.IsEnabled = false;
            domainTxtBox.Clear();
            discoveryTxtBox.Text = "https://disco.crm.dynamics.com/XrmServices/2011/Discovery.svc";
        }

        private void checkBox_Checked(object sender, RoutedEventArgs e)
        {
            smtpaddTxtBox.IsEnabled = true;
         
        }

        private void checkBox_Unchecked(object sender, RoutedEventArgs e)
        {
            smtpaddTxtBox.IsEnabled = false;
        }

        private void btnLogin_Click(object sender, RoutedEventArgs e)
        {

            DisableExchangeControls();
            ExtensionMethods.Refresh(btnLogin);

            if ((bool)!exchangeOnlinechkBox.IsChecked && string.IsNullOrEmpty(ewsTxtBox.Text) || ewsTxtBox.Text == "https://<server>/ews/exchange.asmx")
            {
                MessageBox.Show("Please enter a valid Exchange Web Service URL");
                EnableExchangeControls();
                return;
            }

            if (impersonchckBox.IsChecked == true && string.IsNullOrEmpty(smtpaddTxtBox.Text))
            {
                MessageBox.Show("Please supply the SMTP Address of the mailbox you wish to impersonate.");
                EnableExchangeControls();
                return;
            }
             
            ExchangeAuth = new exchangeauthinfo(exchuserTxtBox.Text, exchPwdBox.Password, (bool)impersonchckBox.IsChecked, smtpaddTxtBox.Text, ewsTxtBox.Text, (bool)exchangeOnlinechkBox.IsChecked, exchDomainTxtBox.Text, exchversionCmbBox.SelectionBoxItem.ToString());
            ExchangeAuth.Run();
            if (!ExchangeAuth.IsServiceReady)
            {
                EnableExchangeControls();
                return;
            }
            exchangeGreenCheck.Visibility = Visibility.Visible;
            CheckStatusAndEnableGo();
        }

        private void CheckStatusAndEnableGo()
        {
            if (ExchangeAuth!= null && ExchangeAuth.IsServiceReady && CrmAuth!= null && CrmAuth.DiscoProxy != null)
            {
                goBtn.IsEnabled = true;
                return;
            }
            return;
        }

        private void DisableExchangeControls()
        {
            btnLogin.IsEnabled = false;
            //currentcredChkBox.IsEnabled = false;
            impersonchckBox.IsEnabled = false;
            exchangeOnlinechkBox.IsEnabled = false;
            exchuserTxtBox.IsEnabled = false;
            exchDomainTxtBox.IsEnabled = false;
            exchPwdBox.IsEnabled = false;
            ewsTxtBox.IsEnabled = false;
            exchversionCmbBox.IsEnabled = false;
            smtpaddTxtBox.IsEnabled = false;
        }

        private void EnableExchangeControls()
        {
            btnLogin.IsEnabled = true;
            //currentcredChkBox.IsEnabled = true;
            impersonchckBox.IsEnabled = true;
            exchangeOnlinechkBox.IsEnabled = true;
            exchuserTxtBox.IsEnabled = true;
            exchDomainTxtBox.IsEnabled = true;
            exchPwdBox.IsEnabled = true;
            ewsTxtBox.IsEnabled = true;
            exchversionCmbBox.IsEnabled = true;
            smtpaddTxtBox.IsEnabled = true;
        }

        private void exchangeOnlinechkBox_Checked(object sender, RoutedEventArgs e)
        {
            ewsTxtBox.Text = "https://outlook.office365.com/ews/exchange.asmx";
            exchversionCmbBox.SelectedIndex = -1;
            exchversionCmbBox.IsEnabled = false;
            exchDomainTxtBox.IsEnabled = false;
            exchDomainTxtBox.Text = null;
            //currentcredChkBox.IsEnabled = false;

        }

        private void exchangeOnlinechkBox_Unchecked(object sender, RoutedEventArgs e)
        {
            ewsTxtBox.Text = "https://<server>/ews/exchange.asmx";
            exchversionCmbBox.IsEnabled = true;
            exchversionCmbBox.SelectedIndex = 1;
            //currentcredChkBox.IsEnabled = true;
            //if ((bool)currentcredChkBox.IsChecked)
            //{
            //    return;
            //}
            exchDomainTxtBox.IsEnabled = true;
        }

        //private void crmcurrentcredChkBox_Checked(object sender, RoutedEventArgs e)
        //{
        //    usernameTxtBox.IsEnabled = false;
        //    usernameTxtBox.Text = "";
        //    passwordBox.Password = "";
        //    passwordBox.IsEnabled = false;
        //    onpremChkBox.IsEnabled = false;
        //    domainTxtBox.IsEnabled = false;
        //    domainTxtBox.Text = "";
        //}

        //private void crmcurrentcredChkBox_Unchecked(object sender, RoutedEventArgs e)
        //{
        //    usernameTxtBox.IsEnabled = true;
        //    passwordBox.IsEnabled = true;
        //    onpremChkBox.IsEnabled = true;
        //    domainTxtBox.IsEnabled = true;
        //}

        //private void currentcredChkBox_Checked(object sender, RoutedEventArgs e)
        //{
        //    exchuserTxtBox.Text = null;
        //    exchuserTxtBox.IsEnabled = false;
        //    exchPwdBox.Password = null;
        //    exchPwdBox.IsEnabled = false;
        //    exchDomainTxtBox.Text = null;
        //    exchDomainTxtBox.IsEnabled = false;
        //    exchangeOnlinechkBox.IsEnabled = false;
        //}

        //private void currentcredChkBox_Unchecked(object sender, RoutedEventArgs e)
        //{
        //    exchuserTxtBox.IsEnabled = true;
        //    exchPwdBox.IsEnabled = true;
        //    exchDomainTxtBox.IsEnabled = true;
        //    exchangeOnlinechkBox.IsEnabled = true;
        //}

        private void goBtn_Click(object sender, RoutedEventArgs e)
        {
            if (String.IsNullOrEmpty(txtTargetMailbox.Text))
            {
                MessageBox.Show("Please supply an email address for the CRM Target Mailbox.");
                return;
            }

            if (!CheckConfiguration())
            {
                return;
            }

            CrmAuth.OrgDetail = (OrganizationDetail)orgsComboBox.SelectedItem;
            CrmAuth.TargetMailbox = txtTargetMailbox.Text;
            CrmAuth.IsQueue = (bool)isQueuechkbox.IsChecked;
            var validationwindow = new ValidatorWindow(CrmAuth, ExchangeAuth) { Owner = this };
            validationwindow.Show();
        }

        private bool CheckConfiguration()
        {
            if (impersonchckBox.IsChecked == true)
            {
                if (string.Compare(smtpaddTxtBox.Text, txtTargetMailbox.Text, true) != 0)
                {
                    MessageBox.Show("The supplied SMTP Address does not match the CRM Target Mailbox. Please check your configuration and try again.");
                    return false;
                }
            }

            if (impersonchckBox.IsChecked == false && exchangeOnlinechkBox.IsChecked == true )
            {
                if (string.Compare(exchuserTxtBox.Text, txtTargetMailbox.Text, true) != 0)
                {
                    MessageBox.Show("The supplied Exchange mailbox does not match the CRM Target Mailbox. Please check your configuration and try again.");
                    return false;
                }
              
            }
            return true;
        }

        private void orgsComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (CrmAuth != null && CrmAuth.Orgbox.SelectedItem != null)
            {
                crmGreenCheck.Visibility = Visibility.Visible;
                //To-Do: Disable the rest of the CRM Deployment Options to lock in the configuration.
                //Add a button to reset the configuration. 
            }
        }

        private void isQueuechkbox_Checked(object sender, RoutedEventArgs e)
        {
            targetLbl.Visibility = Visibility.Visible;
            targetLbl.Visibility = Visibility.Visible;
            
        }

        private void IsQueuechkbox_Unchecked(object sender, RoutedEventArgs e)
        {
            targetLbl.Visibility = Visibility.Visible;
            targetLbl.Visibility = Visibility.Visible;
        }

        private void resetCrmbtn_Click(object sender, RoutedEventArgs e)
        {
            if (CheckCloseWindows())
            {
                CloseOpenWindows();
                CrmAuth = null;
                EnableCrmControls();
                crmGreenCheck.Visibility = Visibility.Hidden;
                orgsComboBox.ItemsSource = null;
                goBtn.IsEnabled = false;
                
            }
            else
            {
                return;
            }

        }

        private void CloseOpenWindows()
        {
            WindowCollection windows = App.Current.Windows;
            foreach (Window window in windows)
            {
                if (window.GetType() != typeof(MainWindow))
                {
                    window.Close();
                }
            }
        }

        private bool CheckCloseWindows()
        {
            if (MessageBox.Show("Resetting configuration will close all open windows. Do you want to continue?", "Confirmation", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
            {
                return true;
            }
            return false;
        }

        private void resetExchbtn_Click(object sender, RoutedEventArgs e)
        {
            if (CheckCloseWindows())
            {
                CloseOpenWindows();
                ExchangeAuth = null;
                EnableExchangeControls();
                exchangeGreenCheck.Visibility = Visibility.Hidden;
                exchversionCmbBox.ItemsSource = null;
                goBtn.IsEnabled = false;
            }
            else
            {
                return;
            }
        }

        private void usernameTxtBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (onpremChkBox.IsChecked == false)
            {
                txtTargetMailbox.Text = ((TextBox)sender).Text;
            }
        }
    }

    public static class ExtensionMethods
    {

        private static Action EmptyDelegate = delegate () { };

        public static void Refresh(this UIElement uiElement)

        {
            uiElement.Dispatcher.Invoke(DispatcherPriority.Render, EmptyDelegate);
        }

    }
}
